package com.itlong.cloud.property.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.property.PadUserAuthPushDTO;
import com.itlong.cloud.POJO.DTO.property.PropertyPadListDTO;
import com.itlong.cloud.POJO.PO.DeviceBusinessElevatorChangeLogPO;
import com.itlong.cloud.POJO.PO.DevicePadInfoPO;
import com.itlong.cloud.POJO.VO.property.PropertyDeviceCloudControllerGetVO;
import com.itlong.cloud.POJO.VO.property.PropertyPadGetOneVO;
import com.itlong.cloud.POJO.VO.property.PropertyPadListVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.constants.RabbitMQConstant;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.CloudElevatorChangeBusinessEnum;
import com.itlong.cloud.enumerate.DataStatusEnum;
import com.itlong.cloud.enumerate.PadChangeBusinessEnum;
import com.itlong.cloud.enumerate.PropertyEquipTypeEnum;
import com.itlong.cloud.property.dao.IPropertyPadDao;
import com.itlong.cloud.property.service.IPropertyPadService;
import com.itlong.cloud.rabbitmq.config.MessageSender;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.utils.data.handler.SqlUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * <desc>
 *      平板业务处理接口实现类
 * </desc>
 *
 * @createDate 2019/01/17
 */
@Service
public class PropertyPadServiceImpl implements IPropertyPadService {

    private static Logger log= LoggerFactory.getLogger(PropertyPadServiceImpl.class);

    @Autowired
    IPropertyPadDao iPropertyPadDao;

    @Autowired
    MessageSender messageSender;

    @Autowired
    RedisService redisService;

    /**
     * <desc>
     *      获取人脸平板列表
     * </desc>
     *
     * @param dto
     * @return
     * @author Jiaqi.X
     * @createDate 2019/01/17
     */
    @Override
    public Page<PropertyPadListVO> getList(PropertyPadListDTO dto) throws Exception {
        if (StringUtils.isBlank(dto.getOrderColumn())) {
            dto.setOrderColumn("pad.create_time");
            dto.setOrderRule("DESC");
        }
        //将DTO转换为Map params
        Map<String, Object> params = SqlUtil.convertBeanToMapParams(dto);
        //分页类默认pageSize为20
        Page<PropertyPadListVO> page = new Page<>();
        page.getPage().setPageSize(dto.getPageSize());
        page.getPage().setCurrentPage(dto.getCurrentPage());
        params.put("currentPage",page.getPage().getStartSlip());
        params.put("pageSize",page.getPage().getPageSize());
        List<PropertyPadListVO> list = iPropertyPadDao.getPage(params);
        //根据数据库查出的数据拼接成返回给前端的数据格式
        for(PropertyPadListVO vo : list){
            String[] buildAndUnit = StringHandlerUtil.splitString(vo.getTempBuildName());
            List<Map<String,Object>> builds = new ArrayList<>();
            for(String build : buildAndUnit){
                Map<String,Object> buildMap = new HashMap<>();
                if(! (build.indexOf("|")<0) ){
                    buildMap.put("buildName",build.substring(0,build.indexOf("|")));
                    buildMap.put("unitName",build.substring(build.indexOf("|")+1,build.length()));
                }else{
                    buildMap.put("buildName",build);
                }
                builds.add(buildMap);
            }
            vo.setBuilds(builds);
        }
        for(PropertyPadListVO propertyPadListVO : list) {
            propertyPadListVO.setIsOnLine("1".equals(redisService.get(RedisConstant.DEVICE_ELEVATOR_IS_ONLINE_KEY + propertyPadListVO.getDeviceUnique())) ? 1 : 0);
        }
        //填充返回数据集
        page.setRows(list, iPropertyPadDao.getPageCount(params));
        return page;
    }

    /**
     * <desc>
     *      删除设备
     * </desc>
     *
     * @param deviceUnique
     * @return
     * @author Jiaqi.X
     * @createDate 2019/01/17
     */
    @Override
    public Integer delete(String deviceUnique) throws Exception {
        iPropertyPadDao.delete(deviceUnique);
        Integer result = iPropertyPadDao.deletePadAddress(deviceUnique);
        //全量更新
        PadUserAuthPushDTO dto = new PadUserAuthPushDTO();
        Map<String,Object> data = new HashMap<>();
        List<PadUserAuthPushDTO> dtos = new ArrayList<>();
        dto.setDeviceUnique(deviceUnique);
        dto.setProjectId(StringHandlerUtil.getProjectIdByDeviceUnique(deviceUnique));
        dto.setPushType(PadChangeBusinessEnum.PUSH_FULL.getCommandType());
        dto.setInstructionType(14);
        dto.setSourceSystem(2);
        dtos.add(dto);
        data.put("data",dtos);
        //发送平板业务指令
        messageSender.send(RabbitMQConstant.RABBITMQ_PAD_USER_AUTH_CHANGE_PUSH_QUEUE, JsonUtil.toJSON(data),
                RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE, RabbitMQConstant.RABBITMQ_PAD_USER_AUTH_CHANGE_PUSH_KEY);
        return 1;
    }

    /**
     * <desc>
     *      获取单个平板信息
     * </desc>
     *
     * @param deviceUnique
     * @return
     * @author Jiaqi.X
     * @createDate 2019/01/17
     */
    @Override
    public PropertyPadGetOneVO getOne(String deviceUnique) throws Exception {
        PropertyPadGetOneVO vo = iPropertyPadDao.getOne(deviceUnique);
        return vo;
    }

    /**
     * <desc>
     *     添加平板信息
     * </desc>
     *
     * @param vo
     * @return
     * @author Jiaqi.X
     * @createDate 2019/01/17
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public String add(PropertyPadGetOneVO vo) throws Exception {
        vo.setDeviceUnique(String.format("%s%s%s",vo.getProjectId(), PropertyEquipTypeEnum.PAD.getType(),vo.getDeviceId()));
        DevicePadInfoPO pad = new DevicePadInfoPO(vo.getDeviceUnique(),vo.getDeviceId(),vo.getDeviceName(),vo.getProjectId(),vo.getDeviceMemo(),vo.getProductTypeId());
        pad.setStatus(DataStatusEnum.NORMAL.getType());
        pad.setCreateTime(new Date());
        pad.setBatchNumber(vo.getBatchNumber());
        iPropertyPadDao.save(SqlUtil.durableData(pad, PlatformConstants.TABLE_SAVE));

        //查看临时升级表是否有该条数据，若有则删除，并向设备推送指令
        if(iPropertyPadDao.isExistInSpecialPad(vo.getDeviceUnique())>0){
            iPropertyPadDao.deleteSpecialPadByDeviceUnique(vo.getDeviceUnique());

//            PadUserAuthPushDTO dto = new PadUserAuthPushDTO();
//            Map<String,Object> data = new HashMap<>();
//            List<PadUserAuthPushDTO> dtos = new ArrayList<>();
//            dto.setDeviceUnique(vo.getDeviceUnique());
//            dto.setProjectId(StringHandlerUtil.getProjectIdByDeviceUnique(vo.getDeviceUnique()));
//            dto.setPushType(PadChangeBusinessEnum.PUSH_FULL.getCommandType());
//            dto.setInstructionType(14);
//            dto.setSourceSystem(2);
//            dtos.add(dto);
//            data.put("data",dtos);
//            //发送平板业务指令
//            messageSender.send(RabbitMQConstant.RABBITMQ_PAD_USER_AUTH_CHANGE_PUSH_QUEUE, JsonUtil.toJSON(data),
//                    RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE, RabbitMQConstant.RABBITMQ_PAD_USER_AUTH_CHANGE_PUSH_KEY);

        }

        return vo.getDeviceUnique();
    }

    /**
     * <desc>
     *      修改平板
     * </desc>
     *
     * @param vo
     * @return
     * @author Jiaqi.X
     * @createDate 2019/01/17
     */
    @Override
    @Transactional(rollbackFor = Exception.class , propagation = Propagation.REQUIRED)
    public String update(PropertyPadGetOneVO vo) throws Exception {
        DevicePadInfoPO pad = new DevicePadInfoPO(vo.getDeviceUnique(),vo.getDeviceId(),vo.getDeviceName(),vo.getProjectId(),vo.getDeviceMemo());
        pad.setBatchNumber(vo.getBatchNumber());
        pad.setUpdateTime(new Date());
        Integer count = iPropertyPadDao.update(SqlUtil.durableData(pad, PlatformConstants.TABLE_UPDATE));
        return vo.getDeviceUnique();
    }

    /**
     * <desc>
     *     添加时检测机号是否重复
     * </desc>
     *
     * @param projectId
     * @param deviceId
     * @return
     * @author Jiaqi.X
     * @createDate 2019/01/17
     */
    @Override
    public Integer checkPadDeviceRepeat(String projectId, String deviceId,Integer type) {
        return iPropertyPadDao.checkPadDeviceRepeat(projectId,deviceId,type);
    }

    /**
     * <desc>
     *      根据传入的设备编号找出绑定它的平板设备
     * </desc>
     * @param deviceUnique 设备编号(门禁或电梯)
     * @return
     * @Author Zhu.yj
     * @createDate  2019/12/17
     */
    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public List<String> getPadDeviceUniqueByBindDevice(String deviceUnique) throws Exception{
        //找出平板绑定的所有设备
        List<String> bindDeviceMapList = iPropertyPadDao.getPadDeviceInfo(deviceUnique);
        return bindDeviceMapList;
    }

    /**
     * <desc>
     *      绑定的设备地址更改时更改平板设备地址
     * </desc>
     *
     * @return
     * @Author Zhu.yj
     * @createDate  2019/12/17
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Integer updatePadAddress(String newUnitIdStr, String deviceUnique, List<String> padDeviceUniqueList,String projectId) throws Exception{
        //取出所有绑定该设备的平板及平板绑定的设备列表
        List<String> newUnitList = StringHandlerUtil.splitStringList(newUnitIdStr);
        List<Map<String, Object>> deviceUniqueMapList = iPropertyPadDao.getBindDeviceUniqueByPad(padDeviceUniqueList);
        //分别更新每个平板的地址
        for (Map<String, Object> deviceUniqueMap : deviceUniqueMapList) {
            List<String> bindDeviceUniqueList = StringHandlerUtil.splitStringList(deviceUniqueMap.get("bindDeviceUnique").toString());
            //找出绑定平板的其他设备的地址
            bindDeviceUniqueList.remove(deviceUnique);
            List<String> bindDeviceUnits = new ArrayList<>();
            Set<String> bindDeviceUnitSet = new HashSet<>();
            if (bindDeviceUniqueList.size() != 0) {
                if (deviceUnique.charAt(8) == PropertyEquipTypeEnum.ELEVATOR.getType()) {
                    bindDeviceUnits = iPropertyPadDao.getPadAddressByElevator(bindDeviceUniqueList);
                } else if (deviceUnique.charAt(8) == PropertyEquipTypeEnum.ENTRANCE.getType()) {
                    bindDeviceUnits = iPropertyPadDao.getPadAddressByEntrance(bindDeviceUniqueList);
                }
                bindDeviceUnitSet = new HashSet<>(bindDeviceUnits);
            }
            //判断平板的地址是否变更1.变更的地址是平板地址中没有的，发全量指令 2.变更的设备是没有地址的，即普通门禁，发全量指令
            if ((!bindDeviceUnitSet.containsAll(newUnitList) && newUnitList.size() != 0) || newUnitList.size() == 0) {
                bindDeviceUnitSet.addAll(newUnitList);
                //移除平板原地址
                iPropertyPadDao.deletePadAddress(deviceUniqueMap.get("deviceUnique").toString());
                if (bindDeviceUnitSet.size() != 0) {
                    List<Map<String, Object>> padAddressList = iPropertyPadDao.getBuildIdsByUnitIds(bindDeviceUnitSet);
                    for (Map<String, Object> params : padAddressList) {
                        params.put("deviceUnique", deviceUniqueMap.get("deviceUnique"));
                        params.put("projectId", projectId);
                        params.put("createTime", new Date());
                    }
                    //平板添加新地址
                    iPropertyPadDao.batchSaveAddress(padAddressList);
                }
                //向平板推送全量更新消息
                List<PadUserAuthPushDTO> dtoList = new ArrayList<>();
                PadUserAuthPushDTO dto = new PadUserAuthPushDTO();
                Map<String, Object> data = new HashMap<>();
                dto.setDeviceUnique(deviceUniqueMap.get("deviceUnique").toString());
                dto.setProjectId(projectId);
                dto.setPushType(PadChangeBusinessEnum.PUSH_FULL.getCommandType());
                dto.setInstructionType(18);
                dto.setSourceSystem(2);
                dtoList.add(dto);
                data.put("data", dtoList);
                messageSender.send(RabbitMQConstant.RABBITMQ_PAD_USER_AUTH_CHANGE_PUSH_QUEUE, JsonUtil.toJSON(data),
                        RabbitMQConstant.RABBITMQ_EQUIP_EXCHANGE, RabbitMQConstant.RABBITMQ_PAD_USER_AUTH_CHANGE_PUSH_KEY);
            }
        }
        return 1;
    }
}
